/*
 Автор: Швейкин Евгений Юрьевич

 Имя модуля: row_cnt

 Функциональное описание:
    
`timescale 1ns / 10ps
*/
//    ********************** НАЧАЛО МОДУЛЯ *********************************************************
module row_cnt
    (   
        input  logic                    reset_n,
        input  logic                    clk,
        
        input                           sof_i,        // Начало кадра
        input                           sor_i,        // Начало строки    
        
        input  logic                    data_wre_i,
        input  logic [15:0]             data_i,
        
        output logic [15:0]             row_cnt_o,

        output                          sof_o,        // Начало кадра
        output                          sor_o,        // Начало строки    
        
        output logic                    data_wre_o,
        output logic [15:0]             data_o,
        output logic [15:0]             frame_cnt_o
        
    );

// ********************** МАКРОСЫ ******************************************************************
// Описывает процесс модуля выделения фронтов сигнала. Строб формируется на том же такте.
// Так же описывает создание новых сигналов с именем <имя сигнала> + <_rise> (<_fall>, <_edge>)
`define FRONT(clk, name)                            \
    logic name``_0;                                 \
    logic name``_rise;                              \
    logic name``_fall;                              \
    logic name``_edge;                              \
    assign name``_rise = name & (~name``_0);        \
    assign name``_fall = name``_0 & (~name);        \
    assign name``_edge = name ^ name``_0;           \
    always_ff @(posedge clk)                        \
    begin                                           \
        name``_0 <= name;                           \
    end

//  ********************* ФУНКЦИИ ******************************************************************

//  ********************* КОНСТАНТЫ ****************************************************************

//  ********************* ТИПЫ ДАННЫХ **************************************************************

//  ********************* ПЕРЕМЕННЫЕ ***************************************************************

//  ********************* БЛОК НЕПРЕРЫВНЫХ НАЗНАЧЕНИЙ ASSIGN ***************************************

    
//  ********************* ОПИСАНИЕ ПРОЦЕССОВ *******************************************************
    `FRONT(clk, data_wre_i)
    `FRONT(clk, sof_i)
    `FRONT(clk, sor_i)

    always_ff @(posedge clk)
    begin
        if (sof_i_rise) begin
            row_cnt_o   <= 16'd0;
            frame_cnt_o <= frame_cnt_o + 16'd1;
        end
        else if (sor_i_rise) begin
            row_cnt_o       <= row_cnt_o + 16'd1;
        end
        else;

        sof_o   <= sof_i_rise;
        sor_o   <= sor_i_rise;
        
        data_wre_o <= data_wre_i_rise;
        data_o     <= data_i;
        
    end
    
endmodule

`undef FRONT